AWS Config と SSM Automation を活用した高リスクセキュリティグループの自動検知と修復を行う方法

AWS Config と SSM Automation を活用した高リスクセキュリティグループの自動検知と修復を行う方法

Clock Icon2024.10.03

はじめに

かつまたです。今回はリソースの監視構成の一環として、SSH、HTTP、HTTPS、RDPといった一般的に使用され、同時にセキュリティリスクも高いポートにおいて、いずれかのポートに対して全開放のインバウンドルールが作成された場合、AWS Configで検知を行い、SSM Automationで該当インバウンドルールを削除するという環境を作成したため手順をご紹介します。構成図は以下の通りです。
Config+Automation.jpg

手順

1.IAMロール作成
2.SSM Automation ドキュメント作成
3.AWS Configルール作成
4.修復アクション設定
5.動作確認

IAMロール作成

SSM Automationがセキュリティグループを管理するための権限を持つIAMロールを作成します。このロールにより、Automationはセキュリティグループの情報を取得し、必要に応じてインバウンドルールを削除できます。
1.「IAM」の「ロールを作成」を選択し、「信頼されたエンティティタイプ」を「AWS のサービス」、「ユースケースを「System Maneger」と選択します。
ロールの信頼されたエンティティ.png

2.「AmazonSSMAutomation」ポリシーを検索し選択します。
SSMポリシー選択.png

3.ロールを作成し、作成したロールの詳細から「許可を追加」→「インラインポリシーを作成」に遷移し、以下のポリシーを記述します。「ランブックを作成」でドキュメントを作成します。

json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeSecurityGroups",
                "ec2:RevokeSecurityGroupIngress"
            ],
            "Resource": "*"
        }
    ]
}

インラインポリシー記述.png

SSM Automation ドキュメント作成

1.「System Manegar」の「ドキュメント」から「ドキュメントの作成」→「オートメーション」を選択します。
スクリーンショット 2024-10-03 14.25.21.png

2.「コード」からIPv4、IPv6のSSH、HTTP、HTTPS、RDPのポートで全開放(0.0.0.0/0)されているインバウンドルールを削除する以下のJSONコードを記載します。

ソースコード
json
description: Disable SSH and RDP ports opened to IP address specified, or to all addresses if no address is specified. Similar to the [RevokeSecurityGroupIngress](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RevokeSecurityGroupIngress.html ) API, the security group must have existing rules specifically on the SSH and RDP ports in order for ingress to be disabled.
schemaVersion: '0.3'
assumeRole: '{{ AutomationAssumeRole }}'
parameters:
  GroupId:
    type: String
    description: (Required) Security Group ID
    allowedPattern: ^([s][g]\-)([0-9a-f]){1,}$
  IpAddressToBlock:
    type: String
    description: (Optional) Additional Ipv4 or Ipv6 address to block access from (ex:1.2.3.4/32)
    allowedPattern: (^$)|^((25[0-5]|(2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})|(^((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?))|(^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}))\/(25[0-5]|2[0-4]\d|[0-1]?\d?\d)$
    default: ''
  AutomationAssumeRole:
    type: String
    description: (Optional) The ARN of the role that allows Automation to perform the actions on your behalf.
    default: ''
mainSteps:
  - name: CustomIpCheck
    action: aws:branch
    inputs:
      Choices:
        - NextStep: DisableSSHFromCustomIpV6
          And:
            - Not:
                Variable: '{{IpAddressToBlock}}'
                StringEquals: ''
            - Variable: '{{ IpAddressToBlock }}'
              Contains: ':'
        - NextStep: DisableSSHFromCustomIpV4
          And:
            - Not:
                Variable: '{{IpAddressToBlock}}'
                StringEquals: ''
            - Not:
                Variable: '{{ IpAddressToBlock }}'
                Contains: ':'
      Default: DisableSSHFromIpV4
  - name: DisableSSHFromIpV4
    action: aws:executeAwsApi
    nextStep: DisableHTTPFromIpV4
    isEnd: false
    onFailure: step:DisableHTTPFromIpV4
    inputs:
      Service: ec2
      Api: RevokeSecurityGroupIngress
      GroupId: '{{GroupId}}'
      IpPermissions:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          IpRanges:
            - CidrIp: 0.0.0.0/0
  - name: DisableHTTPFromIpV4
    action: aws:executeAwsApi
    nextStep: DisableHTTPSFromIpV4
    isEnd: false
    onFailure: step:DisableHTTPSFromIpV4
    inputs:
      Service: ec2
      Api: RevokeSecurityGroupIngress
      GroupId: '{{GroupId}}'
      IpPermissions:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          IpRanges:
            - CidrIp: 0.0.0.0/0
  - name: DisableHTTPSFromIpV4
    action: aws:executeAwsApi
    nextStep: DisableSSHFromIpV6
    isEnd: false
    onFailure: step:DisableSSHFromIpV6
    inputs:
      Service: ec2
      Api: RevokeSecurityGroupIngress
      GroupId: '{{GroupId}}'
      IpPermissions:
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          IpRanges:
            - CidrIp: 0.0.0.0/0
  - name: DisableSSHFromIpV6
    action: aws:executeAwsApi
    nextStep: DisableRDPFromIpV4
    isEnd: false
    onFailure: step:DisableRDPFromIpV4
    inputs:
      Service: ec2
      Api: RevokeSecurityGroupIngress
      GroupId: '{{GroupId}}'
      IpPermissions:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          Ipv6Ranges:
            - CidrIpv6: '::/0'
  - name: DisableRDPFromIpV4
    action: aws:executeAwsApi
    nextStep: DisableRDPFromIpV6
    isEnd: false
    onFailure: step:DisableRDPFromIpV6
    inputs:
      Service: ec2
      Api: RevokeSecurityGroupIngress
      GroupId: '{{GroupId}}'
      IpPermissions:
        - IpProtocol: tcp
          FromPort: 3389
          ToPort: 3389
          IpRanges:
            - CidrIp: 0.0.0.0/0
  - name: DisableRDPFromIpV6
    action: aws:executeAwsApi
    isEnd: true
    inputs:
      Service: ec2
      Api: RevokeSecurityGroupIngress
      GroupId: '{{GroupId}}'
      IpPermissions:
        - IpProtocol: tcp
          FromPort: 3389
          ToPort: 3389
          Ipv6Ranges:
            - CidrIpv6: '::/0'
  - name: DisableSSHFromCustomIpV4
    action: aws:executeAwsApi
    nextStep: DisableRDPFromCustomIpV4
    isEnd: false
    onFailure: step:DisableRDPFromCustomIpV4
    inputs:
      Service: ec2
      Api: RevokeSecurityGroupIngress
      GroupId: '{{GroupId}}'
      IpPermissions:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          IpRanges:
            - CidrIp: '{{ IpAddressToBlock }}'
  - name: DisableRDPFromCustomIpV4
    action: aws:executeAwsApi
    isEnd: true
    inputs:
      Service: ec2
      Api: RevokeSecurityGroupIngress
      GroupId: '{{GroupId}}'
      IpPermissions:
        - IpProtocol: tcp
          FromPort: 3389
          ToPort: 3389
          IpRanges:
            - CidrIp: '{{ IpAddressToBlock }}'
  - name: DisableSSHFromCustomIpV6
    action: aws:executeAwsApi
    nextStep: DisableRDPFromCustomIpV6
    isEnd: false
    onFailure: step:DisableRDPFromCustomIpV6
    inputs:
      Service: ec2
      Api: RevokeSecurityGroupIngress
      GroupId: '{{GroupId}}'
      IpPermissions:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          Ipv6Ranges:
            - CidrIpv6: '{{ IpAddressToBlock }}'
  - name: DisableRDPFromCustomIpV6
    action: aws:executeAwsApi
    isEnd: true
    inputs:
      Service: ec2
      Api: RevokeSecurityGroupIngress
      GroupId: '{{GroupId}}'
      IpPermissions:
        - IpProtocol: tcp
          FromPort: 3389
          ToPort: 3389
          Ipv6Ranges:
            - CidrIpv6: '{{ IpAddressToBlock }}'

スクリーンショット 2024-10-03 14.26.03.png

Configルール作成

1.「AWS Config」の「ルールを追加」から「ルールタイプの指定」で「restricted-common-ports」を検索して選択します。
Configルールタイプ選択.png

2.「ルールを設定」の「パラメータ」でSSH(22)、HTTP(80)、HTTPS(443)、RDP(3389)のポートを検知対象とするポート番号として指定します。Configルールを作成します。
Configルールポートパラメータ設定.png

修復アクション設定

AutomationドキュメントをConfigルールの修復アクションとして設定します。
1.作成したConfigルールの詳細から「アクション」→「修復の管理」を選択します。
スクリーンショット 2024-10-03 14.30.52.png

2.下図の通りに修復アクションを設定し、保存します。

項目 設定値
修復方法を選択 自動修復
修復アクションの詳細 作成したAutomationドキュメント
リソース ID パラメータ GroupID
パラメータ
AutomationAssumeRole 作成したIAMロールのARN名

修復アクション設定.png

動作確認

1.セキュリティグループを作成し、該当ポート番号において0.0.0.0/0を許可するルールを含むインバウンドルールを設定します。
スクリーンショット 2024-10-03 14.40.55.png

2.作成したCongigルール画面上へ非準拠リソースを検出していることを確認し、数分後、作成したセキュリティグループにおいて0.0.0.0/0からの通信を許可する設定のみが削除されていることを確認します。
スクリーンショット 2024-10-03 14.41.27.png

おわりに

作成後のリソースとして残してしまいがちなセキュリティグループに対して監視ルールを構成し自動修復する機能を付与することができます。追加機能として、EventBridge+SNSを利用して検知時にメール通知を行うことで、修復アクション実行に気づくことができて便利かもしれないな、と感じました。ご覧いただきありがとうございました。

参考

Automationドキュメントのソースコードを利用させていただきました。
https://qiita.com/Misshii/items/edb3dd029c24ab035fc0#数分後aws-configのルールrestricted-common-portsが非準拠となりステータスとしてアクションの実行がキューに入りましたと表示されます

アノテーション株式会社について

アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。当社は様々な職種でメンバーを募集しています。「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイトをぜひご覧ください。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.